/**
 * Copyright 2023 Inc.
 **/
package com.myz.java.study.java8.future;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author maoyz0621 on 2023/12/26
 * @version v1.0
 */
@Slf4j
public class CompletionServiceTest {

    final ExecutorService executor = new ThreadPoolExecutor(20, 20, 5, TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(50),
            new ThreadFactoryBuilder().setNameFormat("CompletionService_thread_pool_%d").build(),
            new ThreadPoolExecutor.AbortPolicy());

    final List<Future<Integer>> futures = new ArrayList<>();

    /**
     * 哪个任务先执行完成，get() 方法就会获取到相应的任务结果
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
        CompletionService<Integer> completionService = new ExecutorCompletionService<>(executor);
        for (int i = 10; i > 0; i--) {
            int temp = i;
            futures.add(completionService.submit(() -> {
                Thread.sleep(temp * 10);
                return temp;
            }));
        }

        // 遍历 Future list，通过 get() 方法获取每个 future 结果
        for (int i = 0; i < futures.size(); i++) {
            Integer result = completionService.take().get();
            log.info("result = {}", result);
            // 其他业务逻辑
        }
    }

    @Test
    public void test1() throws Exception {
        for (int i = 10; i > 0; i--) {
            int temp = i;
            futures.add(executor.submit(() -> {
                Thread.sleep(temp * 10);
                return temp;
            }));
        }

        // 遍历 Future list，通过 get() 方法获取每个 future 结果
        for (int i = 0; i < futures.size(); i++) {
            Integer result = futures.get(i).get();
            log.info("result = {}", result);
            // 其他业务逻辑
        }
    }
}